
#include "bscerrada.h"

#include "coord.h"
#include <vector>
#include <cassert>

#include <iostream>

/*
 * Construye una curva bsplien con una cantidad "puntos" de puntos de control
 * La Bspline es forzada a cerrarse.
 *
 * Precondicion:
 *    El parametro "puntos" es la cantidad de elementos del array de Coord
 *    La cantidad de elementos debe cumplir
 *
 *    puntos > grado()
 *    (puntos - grado() - 1) % 2 == 0
 *
 * */       
BsplineCerrada::BsplineCerrada(const std::vector<Coord> &pcontrol)  {
   validarIntegridad(pcontrol);
   int puntos = pcontrol.size();

   int puntosExt;
   puntosExt = puntos + grado();

   this->pcontrol.reserve(puntosExt);

   //pc                 0  1  2  ... puntos-2  puntos-1
   //
   //pcAcopiar          0  1  2  ... puntos-2  puntos-1  0  1  2
   for(int i = 0; i < puntosExt; ++i) {
      this->pcontrol.push_back(pcontrol[i % puntos]);
   }

}

//TODO Constructor temporal
BsplineCerrada::BsplineCerrada(size_t puntos, Coord *puntosControl) {

   std::cout << "TODO :: El constructor BsplineCerrada(size_t puntos, Coord *puntosControl) de la clase BsplineCerrada es una implementacion vieja, utilizar en su lugar el constructor BsplineCerrada(const std::vector<Coord> &pcontrol) PROXIMAMENTE SERA ELIMINADA"<< std::endl;

   assert(puntosControl != 0);
   assert(Bspline::satisfacePrecond(puntos));

   int puntosExt;
   puntosExt = puntos + grado();

   this->pcontrol.reserve(puntosExt);

   //pc                 0  1  2  ... puntos-2  puntos-1
   //
   //pcAcopiar          0  1  2  ... puntos-2  puntos-1  0  1  2
   for(int i = 0; i < puntosExt; ++i) {
      this->pcontrol.push_back(puntosControl[i % puntos]);
   }


}

BsplineCerrada::~BsplineCerrada() { }

Coord BsplineCerrada::centro() const {
   Coord c;
   int cant = pcontrol.size() - grado();

   for(int i = 0; i < cant; ++i){
      c += pcontrol[i];
   }

   return c * (1.0/cant);
}
